package v4_param_route

import (
	"net/http"
)

var _ Server = &HttpServer{}

type HandleFunc func(ctx *Context)

// Server 核心接口尽量少定义方法，衍生方法可以定义在实现上
type Server interface {
	http.Handler
	Start(addr string) error
	// addRoute 用于路由注册
	// addRoute在接口里面是私有的，限制了用户将 无法实现 Server
	// 用户只能通过Get或者Post等合法的方法来注册，那么可以确保 method 参数永远都是对的
	addRoute(method string, path string, handleFunc HandleFunc)
}

// HttpServer 将路由功能拆分到router中进行管理，server 只需要组合它即可
type HttpServer struct {
	router
}

// ServeHTTP 处理请求的入口
func (h *HttpServer) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
	// 请求一来先构造 处理本次请求的 context
	ctx := &Context{
		Req:  request,
		Resp: writer,
	}
	// 开始处理请求
	h.server(ctx)
}

func (h *HttpServer) Start(addr string) error {
	return http.ListenAndServe(addr, h)
}

func (h *HttpServer) Get(path string, handleFunc HandleFunc) { // addRoute 的衍生方法
	h.addRoute(http.MethodGet, path, handleFunc)
}

func (h *HttpServer) Post(path string, handleFunc HandleFunc) { //addRoute 的衍生方法
	h.addRoute(http.MethodGet, path, handleFunc)
}

func (h *HttpServer) Options(path string, handleFunc HandleFunc) { //addRoute 的衍生方法
	h.addRoute(http.MethodGet, path, handleFunc)
}

func (h *HttpServer) Put(path string, handleFunc HandleFunc) { //addRoute 的衍生方法
	h.addRoute(http.MethodGet, path, handleFunc)
}

// server 负责查找路由，并且执行命中的业务逻辑
func (h *HttpServer) server(ctx *Context) {
	mi, ok := h.findRoute(ctx.Req.Method, ctx.Req.URL.Path)
	if !ok || mi.n == nil || mi.n.handler == nil {
		ctx.Resp.WriteHeader(404)
		ctx.Resp.Write([]byte("Not Found"))
		return
	}
	ctx.PathParams = mi.pathParams
	mi.n.handler(ctx)
}
